package com.bio.utils.mail;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.activation.DataHandler;
import javax.mail.BodyPart;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;

import org.apache.commons.mail.ByteArrayDataSource;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.log4j.Logger;

public class MailServer {

	private static Logger logger = Logger.getLogger(MailServer.class.getName());   
	
	private static MailProperties mProperties = new MailProperties();
	
	List receiversTo = new ArrayList(5);
	
    List receiversCC = new ArrayList(5);
	
    private boolean sendHtmlMsg(String[] sendTo,String[] copyTo,String subject,String body,byte[] attachment,String attachFileName,String keywords){  	
    	boolean result = false;
    	if(null == sendTo || sendTo.length == 0){
    		return result;
    	}
    	HtmlEmail email = new HtmlEmail();
    	// init the mail server information
    	email.setHostName(mProperties.getSmtpHost());
    	/* Deal with the mail mode refer to {@MailProperties.MODE_TEST .MODE_PILOT .MODE_PRODUCTION}*/
		receiversTo.clear();
		receiversCC.clear();
		StringBuffer appendInfor4Test = new StringBuffer(100);
		appendInfor4Test.append("<br> actually to: ");
    	for(int i=0; i<sendTo.length; i++){
    		String address = sendTo[i];
    		receiversTo.add(address);
    		appendInfor4Test.append(address+",");
    	}
    	if(null != copyTo && copyTo.length > 0){
    		appendInfor4Test.append("<br> actually copy to: ");
        	for(int i=0; i<copyTo.length; i++){
        		String address = copyTo[i];
        		receiversCC.add(address);
        		appendInfor4Test.append(address+",");
        	}
    	}   		
		
		try{
		   	/* compose the mail content */
			// 1> the receivers
			for(int i=0; i<receiversTo.size(); i++) {
				email.addTo(receiversTo.get(i).toString());
			}

			for(int i=0; i<receiversCC.size(); i++) {
				email.addTo(receiversCC.get(i).toString());
			}

			// 2> The attachment
			if(null != attachment && attachment.length > 0){
	            BodyPart attBody = new MimeBodyPart();
	            ByteArrayDataSource fileDS = new ByteArrayDataSource(attachment,"application/octet-stream");
	            attBody.setDataHandler(new DataHandler(fileDS));
	            attBody.setFileName("".equals(attachFileName.trim()) ? "UnknownFileName":attachFileName);
	            MimeMultipart multipart = new MimeMultipart();
	            multipart.addBodyPart(attBody);
	            email.addPart(multipart);
		    }
			// 3> the from address and name
			String sendFromName = mProperties.getFromName(),sendFromAddr = mProperties.getFromAddress();
			email.setFrom(sendFromAddr, sendFromName);
			// 4> the body and subject
//			String contentType = mProperties.getContentType(),charSet=mProperties.getCharSet();
			email.setSubject(subject);
			email.setMsg(body);
			email.setAuthentication(mProperties.getUsername(), mProperties.getPassword());
			email.setCharset("UTF-8");
		}catch(Exception e){
			logger.error("Error in preparing mail data#"+e);
		}
        try {
			email.send();
			result = true;
		} catch (EmailException e) {
			logger.error("Failed to send out the mail message#"+e);
			result = false;
		} finally{
			//save the mail
			// TODO Save mail or not?
			//saveMail(sendTo,copyTo,subject,body,keywords);
		}
		return result;
    }
	
    /**
	 * @param attachment
	 * @return
	 */
	private byte[] getAttachmentByFile(File attachment){
		byte[] attBytes = null;
		try {
			if(attachment != null){
				attBytes = convertToByteArray(attachment);
			}
			
		} catch (IOException e) {
			logger.error("Can't convert the attachment file to byte array"+e);
			attBytes = null;
		}	
		return attBytes;
	}
	
	public static byte[] convertToByteArray(File file) throws IOException{
		byte[] result = null;
		if(null != file){
			FileInputStream fis = new FileInputStream(file);
			return convertToByteArray(fis);
		}
		return result;
	}
	
	public static byte[] convertToByteArray(InputStream is) throws IOException{
		byte[] result = null;
		if(null != is){
		    ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
		    int ch;
		    while ((ch = is.read()) != -1)
		    {
		       bytestream.write(ch);
		    }
		    result=bytestream.toByteArray();
		    bytestream.close();	
		}
		return result;
	}
	
    public static MailProperties getMProperties() {
		return mProperties;
	}

	public static void setMProperties(MailProperties properties) {
		mProperties = properties;
	}

	public boolean sendMail(String[] sendTo, String[] copyTo, String subject,
			String mailBody, String keyWords) {
		return this.sendHtmlMsg(sendTo, copyTo, subject, mailBody, null, null,keyWords);
	}
    
    public boolean sendMail(String[] sendTo, String[] copyTo, String subject,
			String mailBody, File attachment, String attachFileName,
			String keyWords) {	
		return this.sendHtmlMsg(sendTo, copyTo, subject, mailBody, getAttachmentByFile(attachment),attachFileName,null);		

	}
    
    public boolean sendRegistSuccessMail(String emailAddr){
    	String subject = "宝翼汽修注册成功";
    	String mailBody = "您已经成功注册宝翼汽修管理平台!";
    	boolean result = false;
    	System.out.println("正在发送邮件...");
		result = sendMail(new String[]{emailAddr}, null, subject, mailBody, null);
		if(result){
			System.out.println("邮件发送成功");
		} else {
			System.out.println("邮件发送失败");
		}
		return result;
    }
    
    public boolean sendFindPasswordMail(String emailAddr, String verificationCode){
    	String subject = "宝翼汽修密码重设";
    	StringBuffer mailBody = new StringBuffer();
    	mailBody.append("请点击以下链接重设密码");
    	mailBody.append("<br>");
    	mailBody.append("<a href='http://localhost:8080/medicalManager/user/user!toResetPassword?verifyResetCode="+verificationCode+"&email="+ emailAddr +"'>密码重设</a>");
    	
    	boolean result = false;
    	System.out.println("正在发送邮件...");
		result = sendMail(new String[]{emailAddr}, null, subject, mailBody.toString(), null);
		if(result){
			System.out.println("邮件发送成功");
		} else {
			System.out.println("邮件发送失败");
		}
		return result;
    }
    
	public static void main(String[] args) {
		MailServer mailServer = new MailServer();
		String testerEmail = "119435566@qq.com";
		String testerEmailcc = "1083182510@qq.com";
		String testSubject = "My test mail implementation";
		String mailBody = "This is a test mail, please do not reply.";
		boolean result = false;
		System.out.println("正在发送邮件...");
		result = mailServer.sendMail(new String[]{testerEmail,testerEmailcc}, new String[]{testerEmail,testerEmailcc}, testSubject, mailBody, null);
		if(result){
			System.out.println("邮件发送成功");
		} else {
			System.out.println("邮件发送失败");
		}
	}

}
